package com.authine.cloudpivot.web.api.secondopen.controller;

import com.alibaba.fastjson.JSON;
import com.authine.cloudpivot.engine.api.facade.BizObjectFacade;
import com.authine.cloudpivot.engine.api.model.runtime.BizObjectCreatedModel;
import com.authine.cloudpivot.engine.api.model.runtime.WorkItemModel;
import com.authine.cloudpivot.engine.api.model.runtime.WorkflowInstanceModel;
import com.authine.cloudpivot.web.api.controller.base.BaseController;
import com.authine.cloudpivot.web.api.enums.ProcessType;
import com.authine.cloudpivot.web.api.secondopen.domain.*;
import com.authine.cloudpivot.web.api.secondopen.modules.*;
import com.authine.cloudpivot.web.api.secondopen.service.NcInterfaceService;
import com.authine.cloudpivot.web.api.secondopen.service.QadInterfaceService;
import com.authine.cloudpivot.web.api.secondopen.service.ReimburseService;
import com.authine.cloudpivot.web.api.utils.DateUtil;
import com.authine.cloudpivot.web.api.utils.StringUtils;
import io.jsonwebtoken.*;
import io.jsonwebtoken.lang.Collections;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.dom4j.DocumentException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.*;

import javax.xml.bind.DatatypeConverter;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;


/**
 * NC接口对接控制器
 *
 */
@Api(value = "二开接口", tags = "QAD接口对接控制器")
@RestController
@RequestMapping("/api/ncInterface")
public class NcInterfaceController extends BaseController {

    private static final Logger log = LoggerFactory.getLogger(NcInterfaceController.class);

    @Autowired
    private NcInterfaceService ncInterfaceService;

    @Autowired
    private ReimburseService reimburseService;

    @Autowired
    private QadInterfaceService qadInterfaceService;

    /**
     * 同步个人银行账户信息
     *
     */
    @RequestMapping(value="/syncNcpsn",method = {RequestMethod.POST ,RequestMethod.GET })
    public void syncNcpsn() throws UnsupportedEncodingException {
        log.info("-------------------同步个人银行账户信息开始-----------------------");
        ncInterfaceService.syncNcpsnData();
        log.info("-------------------同步个人银行账户信息结束-----------------------");
    }

    @Scheduled(cron = "0 40 4 * * ?")
    public void syncNcpsnDs() throws UnsupportedEncodingException {
        log.info("-------------------同步个人银行账户信息开始-----------------------");
        ncInterfaceService.syncNcpsnData();
        log.info("-------------------同步个人银行账户信息结束-----------------------");
    }


    /**
     * 同步供应商和银行账户信息
     *
     */
    @RequestMapping(value="/syncNcsup",method = {RequestMethod.POST ,RequestMethod.GET })
    public void syncNcsup(){
        log.info("-------------------同步供应商和银行账户信息开始-----------------------");
        ncInterfaceService.syncNcsupData();
        log.info("-------------------同步供应商和银行账户信息结束-----------------------");
    }

    @Scheduled(cron = "0 45 4 * * ?")
    public void syncNcsupDs(){
        log.info("-------------------同步供应商和银行账户信息开始-----------------------");
        ncInterfaceService.syncNcsupData();
        log.info("-------------------同步供应商和银行账户信息结束-----------------------");
    }


    /**
     * 同步企业银行账户信息
     *
     */
    @RequestMapping(value="/syncNcorgaccount",method = {RequestMethod.POST ,RequestMethod.GET })
    public void syncNcorgaccount(){
        log.info("-------------------同步企业银行账户信息开始-----------------------");
        ncInterfaceService.syncNcorgaccountData();
        log.info("-------------------同步企业银行账户信息结束-----------------------");
    }

    @Scheduled(cron = "0 50 4 * * ?")
    public void syncNcorgaccountDs(){
        log.info("-------------------同步企业银行账户信息开始-----------------------");
        ncInterfaceService.syncNcorgaccountData();
        log.info("-------------------同步企业银行账户信息结束-----------------------");
    }


    /**
     * 同步结算方式
     *
     */
    @RequestMapping(value="/syncNcsettling",method = {RequestMethod.POST ,RequestMethod.GET })
    public void syncNcsettling(){
        log.info("-------------------同步结算方式信息开始-----------------------");
        ncInterfaceService.syncNcsettlingData();
        log.info("-------------------同步结算方式信息结束-----------------------");
    }

    @Scheduled(cron = "0 55 4 * * ?")
    public void syncNcsettlingDs(){
        log.info("-------------------同步企业银行账户信息开始-----------------------");
        ncInterfaceService.syncNcorgaccountData();
        log.info("-------------------同步企业银行账户信息结束-----------------------");
    }


    /**
     * 同步银行承兑汇票的票据信息
     *
     */
    @RequestMapping(value="/syncNcexchange",method = {RequestMethod.POST ,RequestMethod.GET })
    public void syncNcexchange(){
        log.info("-------------------同步银行承兑汇票的票据信息开始-----------------------");
        ncInterfaceService.syncNcexchangeData();
        log.info("-------------------同步银行承兑汇票的票据信息结束-----------------------");
    }

    @Scheduled(cron = "0 0 5 * * ?")
    public void syncNcexchangeDs(){
        log.info("-------------------同步企业银行账户信息开始-----------------------");
        ncInterfaceService.syncNcorgaccountData();
        log.info("-------------------同步企业银行账户信息结束-----------------------");
    }

//    /**
//     * nc付款结算单
//     *
//     */
//    @RequestMapping(value="/pushNcFkjsD",method = {RequestMethod.POST ,RequestMethod.GET })
//    public void pushNcFkjsD(){
//        log.info("-------------------同步银行承兑汇票的票据信息开始-----------------------");
//        ncInterfaceService.pushNcFkjsDData(Cmppaybill cmppaybill);
//        log.info("-------------------同步银行承兑汇票的票据信息结束-----------------------");
//    }



    /**
     * 报销，付款结束调用银企直连接口
     *
     * @param objId
     * @return
     */
    @RequestMapping(value="/paymentPreInYqzl",method = {RequestMethod.POST ,RequestMethod.GET })
    @ApiOperation(value = "报销，付款结束调用银企直连接口", notes = "报销结束调用银企直连接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "objId", value = "业务对象id", dataType = "String", paramType = "query")
    })
    public AjaxResult paymentPreInYqzl( String objId,String processCode,String fkyhzh) throws DocumentException {
        log.info("获取参数:objId={}", objId);
        if (StringUtils.isBlank(objId)) {
            log.info("参数不完整，直接结束");
            return AjaxResult.error("300","参数不完整，直接结束");
        }
        BizObjectFacade bizObjectFacade = super.getBizObjectFacade();
        //获取业务数据
        BizObjectCreatedModel bizObject = bizObjectFacade.getBizObject(processCode, objId);
        if (bizObject == null) {
            log.info("业务对象不存在");
            return AjaxResult.error("300","业务对象不存在");
        }
        String wId = bizObject.getWorkflowInstanceId();
        log.info("TargetOwner:wId={}", wId);
        WorkflowInstanceModel wiModel = super.getWorkflowInstanceFacade().getWorkflowInstance(wId);
        if (wiModel == null) {
            log.info("业务流程对象不存在");
            return AjaxResult.error("300","业务流程对象不存在");
        }

//        this.generateVoucher(objId,processCode);

//        if("wbxcbxdlc".equals(processCode)){
//            processName="外埠行车报销单";
//        }else if("clfbxlc".equals(processCode)){
//            processName="差旅费报销单";
//        }

        //所属公司
        String ssgs = (String) bizObject.get("ssgs");
        //支付金额
        BigDecimal zfjeB = (BigDecimal) bizObject.get("zfje");
        Double zfje=zfjeB.doubleValue();
        String gh="";
        String gysCode="";
        if("lxpjbxlc".equals(processCode)){
            gh = (String)bizObject.get("bxrygh");
        }else if("hksqdlc".equals(processCode)){
            //工号
            gysCode = (String)bizObject.get("gysCode");
            gh = (String)bizObject.get("gysCode");
        }else if("jkdlc".equals(processCode)){
            gh = (String)bizObject.get("jkrygh");
        }else if("yyfbxd3".equals(processCode)){
            gh = (String)bizObject.get("bxrygh");
        }else if("clfbxlc".equals(processCode)){
            gh = (String)bizObject.get("bxrygh");
        }else if("wbxcbxdlc".equals(processCode)){
            //工号
            gh = (String)bizObject.get("gh");
        }else if("gysyfksqblc".equals(processCode)){
            gh = (String)bizObject.get("gysbm");
        }


        //收款银行账户
        String skyhzh = (String)bizObject.get("yhzh");
        //付款银行账户
//        String fkyhzh = (String)bizObject.get("yhh");
        //收款银行姓名
        String skr = (String)bizObject.get("skr");
        //摘要
        String zy = (String)bizObject.get("zy");

        //收款银行名称
        String skyhmc = (String)bizObject.get("khzh");
        //单据号
//        String sequenceNo = (String)bizObject.get("sequenceNo");
        //创建时间
        Date createdTime = bizObject.getCreatedTime();
        String accounttype="1";

        Cmppaybill cmppaybill=new Cmppaybill();
        cmppaybill.setPkOrg("a01");
        cmppaybill.setBillDate(DateUtil.covertDate(createdTime,null));
        cmppaybill.setCreationtime(DateUtil.covertDate(new Date(),null));
        cmppaybill.setBillmakerDate(DateUtil.covertDate(new Date(),null));
        cmppaybill.setPrimalMoney(zfje);
        cmppaybill.setLocalMoney(zfje);
        cmppaybill.setGroupLocal(zfje);
        cmppaybill.setGlobalLocal(zfje);
//        gh="11217";
        if("gysyfksqblc".equals(processCode) || "hksqdlc".equals(processCode)){
            cmppaybill.setObjecttype(1);
            cmppaybill.setPkSupplier(gh);
            skr=(String)bizObject.get("skdwqc");
            skyhmc = (String)bizObject.get("hrhdd");
            accounttype="0";
        }else{
            cmppaybill.setObjecttype(3);
            cmppaybill.setPkBusiman(gh);
        }
        cmppaybill.setMemo(zy);
        cmppaybill.setPkAccount(skyhzh);
        cmppaybill.setPkOppaccount(fkyhzh);
        cmppaybill.setSavedate(DateUtil.covertDate(createdTime,null));
        cmppaybill.setDef1(processCode+"-"+objId);

        List<CmppaybillDeatail> cmppaybillDeatails=new ArrayList<>();
        CmppaybillDeatail cmppaybillDeatail=new CmppaybillDeatail();
        cmppaybillDeatail.setAccountname(skr);
        cmppaybillDeatail.setBillDate(DateUtil.covertDate(createdTime,null));
        cmppaybillDeatail.setCreationtime(DateUtil.covertDate(new Date(),null));
        cmppaybillDeatail.setGlobalLocalPay(zfje);
        cmppaybillDeatail.setGroupLocalPay(zfje);
        cmppaybillDeatail.setModifiedtime(DateUtil.covertDate(new Date(),null));

        if("gysyfksqblc".equals(processCode) || "hksqdlc".equals(processCode)){
            cmppaybillDeatail.setObjecttype(1);
            cmppaybillDeatail.setPkSupplier(gh);
        }else{
            cmppaybillDeatail.setObjecttype(3);
            cmppaybillDeatail.setPkBusiman(gh);
        }
        cmppaybillDeatail.setPayLocal(zfje);
        cmppaybillDeatail.setPayPrimal(zfje);
        cmppaybillDeatail.setPkAccount(skyhzh);
        cmppaybillDeatail.setPkOppaccount(fkyhzh);
        cmppaybillDeatail.setPkOrg("a01");
        cmppaybillDeatail.setMemo(zy);
        cmppaybillDeatail.setAccountopenbank(skyhmc);
        cmppaybillDeatail.setAccounttype(accounttype);
        cmppaybillDeatails.add(cmppaybillDeatail);

        cmppaybill.setCmppaybillDeatails(cmppaybillDeatails);

        Sendresult sendresult=ncInterfaceService.pushNcFkjsDData(cmppaybill);
        if(sendresult!=null && "1".equals(sendresult.getResultcode())){
            log.info("调用银企直连成功，信息为：{}",JSON.toJSONString(sendresult));
            int num=reimburseService.updPaymentStatus(processCode,objId,"生成付款结算单成功，正在付款中...");
            log.info("调用updPaymentStatus结束，成功条数为：{}",num);
            return AjaxResult.success("调用付款结算单成功");
        }else{
            log.info("调用银企直连失败，失败信息为：{}",JSON.toJSONString(sendresult));
            return AjaxResult.error("调用付款结算单失败，请更改错误信息后提交，失败信息为:{}",JSON.toJSONString(sendresult));
        }
    }


    /**
     * 报销自动提交财务确认节点，并生成凭证
     *
     * @param objId
     * @return
     */
    public QadResultVO generateVoucher(String objId,String processCode,String payDate) {
        log.info("获取参数:objId={},processCode={},identtify={}", objId,processCode);
        if (StringUtils.isBlank(objId) || StringUtils.isBlank(processCode)) {
            log.info("参数不完整，直接结束");
            return null;
        }
        BizObjectFacade bizObjectFacade = super.getBizObjectFacade();
        //获取业务数据
        BizObjectCreatedModel bizObject = bizObjectFacade.getBizObject(processCode, objId);
        if (bizObject == null) {
            log.info("业务对象不存在");
            return null;
        }

//        String wId = bizObject.getWorkflowInstanceId();
//        //根据流程实例ID查询待办任务信息
//        List<WorkItemModel> workItemModels=this.getWorkflowInstanceFacade().getWorkItems(wId, false);
//        //提交任务
//        if(!Collections.isEmpty(workItemModels)){
//            for (WorkItemModel workItemModel : workItemModels) {
//                if(workItemModel.getActivityName().equals("财务确认")){
//                    //如果是财务确认节点，则提交审批
//                    Boolean isSubmit=this.getWorkflowInstanceFacade().submitWorkItem(workItemModel.getParticipant(),workItemModel.getId());
//
//                    if(isSubmit){
//                        log.info("流程提交成功，待办任务id为："+workItemModel.getId());
//                    }else{
//                        log.info("流程提交失败，待办任务id为："+workItemModel.getId());
//                    }
//                }
//            }
//        }

        //根据员工id查询所属公司，然后查询会计单位
        String ssgs=(String) bizObject.get("ssgs");
        //会计单位
        String kjdw="";
        if(StringUtils.isNotBlank(ssgs)){
            List<Ie6s6Kjdwxx> kjdwxxes=reimburseService.getKjdwxxBySsgs(ssgs);
            if(!Collections.isEmpty(kjdwxxes)){
                kjdw=kjdwxxes.get(0).getKjdwCode();
            }
        }

        VoucherVO voucherVO=new VoucherVO();
        voucherVO.setMdmIdtEffdate(DateUtil.getCurrentDate("yyyy-MM-dd"));
        //摘要
        voucherVO.setMdmIcPostingText((String) bizObject.get("zy"));
        List<VoucherDeatailVO> voucherDeatailVOS=new ArrayList<>();
        MdmBankEntry mdmBankEntry=new MdmBankEntry();
        if("lxpjbxlc".equals(processCode)){
            voucherDeatailVOS=reimburseService.convertPzxx(bizObject,"jfkmSheet","dfkmSheet");
        }else if("hksqdlc".equals(processCode)){
            voucherDeatailVOS=reimburseService.convertPzxx(bizObject,"hkjfkmSheet","hkdfkmSheet");
        }else if("jkdlc".equals(processCode)){
            voucherDeatailVOS=reimburseService.convertPzxx(bizObject,"jkdjfkmSheet","jkddfkmSheet");
        }else if("yyfbxd3".equals(processCode)){
            voucherDeatailVOS=reimburseService.convertPzxx(bizObject,"yyfjfkmSheet","yyfdfkmSheet");
        }else if("clfbxlc".equals(processCode)){
            voucherDeatailVOS=reimburseService.convertPzxx(bizObject,"clfjfkmSheet","clfdfkmSheet");
        }else if("wbxcbxdlc".equals(processCode)){
            voucherDeatailVOS=reimburseService.convertPzxx(bizObject,"wbxcjfkmSheet","wbxcdfkmSheet");
        }else if("gysyfksqblc".equals(processCode)){
            mdmBankEntry=reimburseService.convertYhfl(bizObject,"yfhkjfkmSheet","yfhkdfkmSheet",payDate);
            mdmBankEntry.setMdmIcCompnayCode(kjdw);
        }
        voucherVO.setMdmMFpostingline(voucherDeatailVOS);
        voucherVO.setMdmIcCompnayCode(kjdw);
        QadResultVO qadResultVO=new QadResultVO();
        if("gysyfksqblc".equals(processCode)){
            //调用银行分录
            qadResultVO=qadInterfaceService.qadInMdmBankEntryPost(mdmBankEntry);
        }else{
            //调用总账凭证
            qadResultVO=qadInterfaceService.generateQadVoucher(voucherVO);
        }

        log.info("--------qad生成凭证返回信息为:{}---------"+JSON.toJSONString(qadResultVO));
        return qadResultVO;

    }


    /**
     * 付款金额为0自动生成凭证
     *
     * @param objId
     * @return
     */
    @RequestMapping(value="/zeroGenerateVoucher",method = {RequestMethod.POST ,RequestMethod.GET })
    public AjaxResult zeroGenerateVoucher(String objId,String processCode) {
        log.info("获取参数:objId={},processCode={},identtify={}", objId,processCode);
        if (StringUtils.isBlank(objId) || StringUtils.isBlank(processCode)) {
            log.info("参数不完整，直接结束");
            return null;
        }
        BizObjectFacade bizObjectFacade = super.getBizObjectFacade();
        //获取业务数据
        BizObjectCreatedModel bizObject = bizObjectFacade.getBizObject(processCode, objId);
        if (bizObject == null) {
            log.info("业务对象不存在");
            return null;
        }

        //根据员工id查询所属公司，然后查询会计单位
        String ssgs=(String) bizObject.get("ssgs");
        //会计单位
        String kjdw="";
        if(StringUtils.isNotBlank(ssgs)){
            List<Ie6s6Kjdwxx> kjdwxxes=reimburseService.getKjdwxxBySsgs(ssgs);
            if(!Collections.isEmpty(kjdwxxes)){
                kjdw=kjdwxxes.get(0).getKjdwCode();
            }
        }

        VoucherVO voucherVO=new VoucherVO();
        voucherVO.setMdmIdtEffdate(DateUtil.getCurrentDate("yyyy-MM-dd"));
        //摘要
        voucherVO.setMdmIcPostingText((String) bizObject.get("zy")+"-"+bizObject.getSequenceNo());
        List<VoucherDeatailVO> voucherDeatailVOS=new ArrayList<>();
        MdmBankEntry mdmBankEntry=new MdmBankEntry();
        if("lxpjbxlc".equals(processCode)){
            voucherDeatailVOS=reimburseService.convertPzxx(bizObject,"jfkmSheet","dfkmSheet");
        }else if("hksqdlc".equals(processCode)){
            voucherDeatailVOS=reimburseService.convertPzxx(bizObject,"hkjfkmSheet","hkdfkmSheet");
        }else if("jkdlc".equals(processCode)){
            voucherDeatailVOS=reimburseService.convertPzxx(bizObject,"jkdjfkmSheet","jkddfkmSheet");
        }else if("yyfbxd3".equals(processCode)){
            voucherDeatailVOS=reimburseService.convertPzxx(bizObject,"yyfjfkmSheet","yyfdfkmSheet");
        }else if("clfbxlc".equals(processCode)){
            voucherDeatailVOS=reimburseService.convertPzxx(bizObject,"clfjfkmSheet","clfdfkmSheet");
        }else if("wbxcbxdlc".equals(processCode)){
            voucherDeatailVOS=reimburseService.convertPzxx(bizObject,"wbxcjfkmSheet","wbxcdfkmSheet");
        }else if("gysyfksqblc".equals(processCode)){
            mdmBankEntry=reimburseService.convertYhfl(bizObject,"yfhkjfkmSheet","yfhkdfkmSheet",DateUtil.getCurrentDate("yyyy-MM-dd"));
            mdmBankEntry.setMdmIcCompnayCode(kjdw);
        }
        voucherVO.setMdmMFpostingline(voucherDeatailVOS);
        voucherVO.setMdmIcCompnayCode(kjdw);
        QadResultVO qadResultVO=new QadResultVO();
        if("gysyfksqblc".equals(processCode)){
            //调用银行分录
            qadResultVO=qadInterfaceService.qadInMdmBankEntryPost(mdmBankEntry);
        }else{
            //调用总账凭证
            qadResultVO=qadInterfaceService.generateQadVoucher(voucherVO);
        }
        if(qadResultVO!=null && "10000".equals(qadResultVO.getCode())){
            //成功后将凭证号填入表单内
            reimburseService.updGenerateVoucher(processCode,objId,qadResultVO.getPzh(),qadResultVO.getMsg());
            log.info("生成凭证成功，成功信息为："+JSON.toJSONString(qadResultVO));
            return AjaxResult.success("生成凭证成功");
        }else{
            //失败后将凭证信息填入表单内
            reimburseService.updGenerateVoucher(processCode,objId,"","生成凭证失败，"+qadResultVO.getMsg());
            log.info("生成凭证失败，错误信息为："+qadResultVO.getMsg());
            return AjaxResult.error("生成凭证失败，请更改错误信息后提交，失败信息为:{}",JSON.toJSONString(qadResultVO));
        }
    }

    /**
     * 银企直连付款回传接口
     *
     * @return
     */
    @GetMapping(value = "/bankEnterpriseDirectLinkPayment")
    public AjaxResult bankEnterpriseDirectLinkPayment(@RequestParam(name = "def1") String def1,@RequestParam(name = "payDate") String payDate) {
//        if(yqzlFkResultVO!=null){
//            return AjaxResult.error("-1","调用失败，参数对象不能为空");
//        }
        log.info("开始调用bankEnterpriseDirectLinkPayment，参数def1为{},payDate为{}",def1,payDate);
        if(StringUtils.isEmpty(def1) || StringUtils.isEmpty(payDate)){
            return AjaxResult.error("-1","调用失败，def1和payDate不能为空");
        }
//        String def1=yqzlFkResultVO.getDef1();
        String[] def=def1.split("-");
        if(def.length>0){
            String processCode= def[0];
            String objId= def[1];
            //更改表单付款状态
            int num=reimburseService.updPaymentStatus(processCode,objId,"已完成付款");
            log.info("调用bankEnterpriseDirectLinkPayment结束，成功条数为：{}",num);
            //调用生成凭证接口
            QadResultVO qadResultVO=this.generateVoucher(objId,processCode,payDate);
            if(qadResultVO!=null && "10000".equals(qadResultVO.getCode())){
                //成功后将凭证号填入表单内
                reimburseService.updGenerateVoucher(processCode,objId,qadResultVO.getPzh(),qadResultVO.getMsg());
                log.info("生成凭证成功，成功信息为："+JSON.toJSONString(qadResultVO));
            }else{
                //成功后将凭证号填入表单内
                reimburseService.updGenerateVoucher(processCode,objId,"",qadResultVO.getMsg());
                log.info("生成凭证失败，错误信息为："+JSON.toJSONString(qadResultVO));
            }
        }
        return AjaxResult.success("调用成功");
    }


}
